﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AssetBundles;
using System.Resources;

/// <summary>
// 通过Facade模式限制提供给外部调用的各个manager的方法接口，未在Facade内提供的，不可绕过Facade去找对应的manager直接调用，将各个manger子系统解耦
/// </summary>
public class MainFacade : Singleton<MainFacade>
{
    public const string MANAGER_NAME = "GameManager";

    //各类manager初始化时比较耗时，故在单例类里初始后在内存内持久化存在
    static Dictionary<string, object> m_managers = new Dictionary<string, object>();

    private static MainFacade _instance = null;

    [Obsolete("instance func is Obsolete，use Instance", false)]
    public static MainFacade instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new MainFacade();
            }
            return _instance;
        }
    }

    private GameObject _manager = null;
    public GameObject manager
    {
        get
        {
            if (_manager == null)
            {
                _manager = GameObject.Find("Main");
            }
            return _manager;
        }
    }
    private Main _main = null;
    public Main main
    {
        get
        {
            if (_main == null)
            {
                _main = manager.gameObject.GetComponent<Main>();
            }
            return _main;
        }
    }

    public void StartGame()
    {
        //file:///C:/Users/Administrator/AppData/LocalLow/ht/borderExpansion/BorderExpansion/
        //Debug.Log(MainConfigPath.persistentDataPath + MainConst.AppName + "/");
        //BorderExpansion/
        Debug.unityLogger.logEnabled = Application.isEditor;
        MainUtil.Log("ab下载后的本地平台存储目录路径(PersistentDataPath)" + MainConfigPath.PersistentDataPath());
        //C:/ Users / Administrator / AppData / LocalLow / ht / borderExpansionProj
        //Debug.Log(Application.persistentDataPath);
        this.AddManager<TipManager>();
        this.AddManager<Timer>();
        this.AddManager<SoundManager>();
        this.AddManager<AssetBundleManager>();
        this.AddManager<LuaManager>();
        this.AddManager<ResourceManager>();
        this.AddManager<GameManager>();
    }

    /// <summary>
    /// 添加各个manager组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="managerName"></param>
    /// <returns></returns>
    private T AddManager<T>(string managerName) where T : Component
    {
        object temp = null;
        m_managers.TryGetValue(managerName, out temp);
        if (temp != null)
        {
            return (T)temp;
        }
        Component added = manager.AddComponent<T>();
        MainUtil.Log("添加manager:" + managerName);
        m_managers.Add(managerName, added);
        return (T)added;
    }

    /// <summary>
    /// 添加各个manager组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T AddManager<T>() where T : Component
    {
        object temp = null;
        string managerName = typeof(T).ToString();
        m_managers.TryGetValue(managerName, out temp);
        if (temp != null)
        {
            return (T)temp;
        }
        Component added = manager.AddComponent<T>();
        MainUtil.Log("添加manager:" + managerName);
        m_managers.Add(managerName, added);
        return (T)added;
    }

    /// <summary>
    /// 添加各个manager组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="managerType"></param>
    /// <returns></returns>
    public T AddManager<T>(Type managerType) where T : Component
    {
        return AddManager<T>(managerType.ToString());
    }

    /// <summary>
    /// 获取manager组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="managerName"></param>
    /// <returns></returns>
    private T GetManager<T>(string managerName) where T : Component
    {
        object temp = null;
        if (!m_managers.TryGetValue(managerName, out temp))
        {
            return default(T);
        }
        return (T)temp;
    }

    private T GetManager<T>(Type managerType) where T : Component
    {
        return GetManager<T>(managerType.ToString());
    }

    /// <summary>
    /// 获取manager组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T GetManager<T>() where T : Component
    {
        return GetManager<T>(typeof(T));
    }

    ///---ResourceManager  接口

    //public void LoadAsset(string assetBundleName, string assetName, Type objType, Action<UnityEngine.Object> callBack)
    //{
    //    this.GetManager<ResourceManager>().LoadAsset(assetBundleName, assetName, objType, null, callBack);
    //}

    public void LoadAsset(string assetBundleName, string assetName, Type objType, Action<UnityEngine.Object, Dictionary<string, object>> callBack)
    {
        this.GetManager<ResourceManager>().LoadAsset(assetBundleName, assetName, objType, null, callBack);
    }

    public void LoadAsset(string assetBundleName, string assetName, Type objType, Dictionary<string, System.Object> paramDic, Action<UnityEngine.Object, Dictionary<string, object>> callBack)
    {
        this.GetManager<ResourceManager>().LoadAsset(assetBundleName, assetName, objType, paramDic, callBack);
    }

    public ResourceManager ResourceMgr
    {
        get
        {
            return this.GetManager<ResourceManager>();
        }
    }

    ///----uimanager  接口
    public void CreatePanel(string abName, string assetName,
        UIManager.DisplayLevel displayLv = UIManager.DisplayLevel.mainview,
        UIManager.DestroyType destroyType = UIManager.DestroyType.IMMEDIATE_DESTROY
        )//, Action<UnityEngine.Object> callBack,
    {
        this.GetManager<UIManager>().CreatePanel(abName, assetName, typeof(GameObject), displayLv, destroyType);
    }
    //public void DestroyUI(GameObject ogj) {
    //    this.GetManager<UIManager>().DestroyUI(ogj);
    //}
    ///// <summary>
    ///// 获取创建的UI对象,name:abname_assetname.tolower
    ///// </summary>
    ///// <param name="name"></param>
    ///// <returns></returns>
    //public GameObject GetUIComponent(string name)
    //{
    //    return this.GetManager<UIManager>().GetUIComponent(name);
    //}

    public UIManager UIMgr
    {
        get
        {
            return this.GetManager<UIManager>();
        }
    }

    ///----------Timer 接口
	public Timer Timer
    {
        get
        {
            return this.GetManager<Timer>();
        }
    }

    public TipManager TipMgr
    {
        get
        {
            return this.GetManager<TipManager>();
        }
    }

    ///----------SoundManager 接口
    public SoundManager SoundMgr
    {
        get
        {
            return this.GetManager<SoundManager>();
        }
    }

    public LuaManager LuaMgr
    {
        get
        {
            return this.GetManager<LuaManager>();
        }
    }

    //public int AddTimer(float delayTime, Action callBack, int repeatTimes)
    //{
    //    return this.GetManager<Timer>().AddTimer(delayTime, callBack, repeatTimes);
    //}

    //public void RemoveTimer(Action callBack)
    //{
    //    this.GetManager<Timer>().RemoveTimer(callBack);
    //}

    //public void RemoveTimer(int timerId)
    //{
    //    this.GetManager<Timer>().RemoveTimer(timerId);
    //}

    //public void UpdateBeat(object obj, Action callBack)
    //{
    //    this.GetManager<Timer>().UpdateBeat(obj,callBack);
    //}
    //public void RemoveUpdateBeat(object obj)
    //{
    //    this.GetManager<Timer>().RemoveUpdateBeat(obj);
    //}

    //public void LateUpdateBeat(object obj, Action callBack)
    //{
    //    this.GetManager<Timer>().LateUpdateBeat(obj, callBack);
    //}
    //public void RemoveLateUpdateBeat(object obj)
    //{
    //    this.GetManager<Timer>().RemoveLateUpdateBeat(obj);
    //}
    //public void FixedUpdateBeat(object obj, Action callBack)
    //{
    //    this.GetManager<Timer>().FixedUpdateBeat(obj, callBack);
    //}
    //public void RemoveFixedUpdateBeat(object obj)
    //{
    //    this.GetManager<Timer>().RemoveFixedUpdateBeat(obj);
    //}


}
